package uit.nfcmenu.util;


import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.NinePatchDrawable;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.SystemClock;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class UiUtilities {
	static String tag = UiUtilities.class.getSimpleName();
	
	/*
	 * Calculate in screen
	 */
	/**
	 * This method convets dp unit to equivalent device specific value in pixels. 
	 * 
	 * @param dp A value in dp(Device independent pixels) unit. Which we need to convert into pixels
	 * @param context Context to get resources and device specific display metrics
	 * @return A float value to represent Pixels equivalent to dp according to device
	 */
	public static float convertDpToPixel(Context context, float dp){
	    Resources resources = context.getResources();
	    DisplayMetrics metrics = resources.getDisplayMetrics();
	    float px = dp * (metrics.densityDpi/160f);
	    return px;
	}
	/**
	 * This method converts device specific pixels to device independent pixels.
	 * 
	 * @param px A value in px (pixels) unit. Which we need to convert into db
	 * @param context Context to get resources and device specific display metrics
	 * @return A float value to represent db equivalent to px value
	 */
	public static float convertPixelsToDp(Context context, float px) {
		Resources resources = context.getResources();
		DisplayMetrics metrics = resources.getDisplayMetrics();
		float dp = px / (metrics.densityDpi / 160f);
		return dp;
	}
	
	/**
	 * Must <uses-permission android:name="android.permission.BLUETOOTH" />
	 */
	public static String getMacAddress(Context context) {
		WifiManager wimanager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		String address = wimanager.getConnectionInfo().getMacAddress();
    	Log.e(tag, "getMacAddress() address="+address);
    	return address;
	}

	/*
	 * Controls
	 */
	public interface ICallBack {
		public void callBack(int id);
	}

	public static int getVisibilityReversed(String string) {
		if (string == null) {
			return View.GONE;
		}
		return ("".equals(string)) ? View.VISIBLE : View.INVISIBLE;
	}

	/**
	 * This method is used to the case log-in with username/password fields.
	 * @param textView: given TextView
	 * @return VISIBLE if given TextView is blank, else INVISIBLE if there has text.
	 * For other case: given TextView is null, this return GONE
	 */
	public static int getVisibilityReversed(TextView textView) {
		if (textView == null) {
			return View.GONE;
		}
		int visibility = ("".equals(textView.getText().toString())) ? View.VISIBLE : View.INVISIBLE;
		//Log.i(tag, textView+":"+visibility);
		return visibility;
	}
	
	public static TextWatcher getListener_textChanged(final ICallBack callback, final int id) {
		return new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				callback.callBack(id);
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
			
			@Override
			public void afterTextChanged(Editable s) { }
		};
	}
	
	public static TextWatcher getListener_textChanged(final Runnable callback) {
		return new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				callback.run();
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
			
			@Override
			public void afterTextChanged(Editable s) { }
		};
	}

	public static OnFocusChangeListener getListener_text_focusChanged(
			final ICallBack callback, final int id) {
		return new OnFocusChangeListener() {
			
			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				callback.callBack(id);
			}
		};
	}
	
	public static void startNewActivityAndFinishThis(Activity actThis, Class<?> actNew) {
		Intent intent = new Intent(actThis, actNew); 
		actThis.finish();
		actThis.startActivity(intent);
	}
	
	public static void showKeyboard(Context context, EditText editText) {
//		Log.i(tag, "showKeyboard()");
//		InputMethodManager imm = (InputMethodManager) context
//				.getSystemService(Context.INPUT_METHOD_SERVICE);
//      imm.showSoftInput(editText, 0);  // wrong
//		imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); // 1 // wrong
//		imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED); // 2 // wrong
//		imm.restartInput(editText);
		
		// ttnlan: this code make "force close" in 480x850 (Google Milestone) >
		try {
			editText.requestFocus();
			editText.dispatchTouchEvent(MotionEvent.obtain(
					SystemClock.uptimeMillis(), 
					SystemClock.uptimeMillis(), 
					MotionEvent.ACTION_DOWN , 0, 0, 0));
			editText.dispatchTouchEvent(MotionEvent.obtain(
					SystemClock.uptimeMillis(), 
					SystemClock.uptimeMillis(), 
					MotionEvent.ACTION_UP , 0, 0, 0));
		} catch (NullPointerException e) {
//			e.printStackTrace();
//			Log.e(tag, "This code make null for the first time use keyboard in Milestone" +
//					"he ask me choose which Input Method will be used for Edit Text: " +
//					"\"Android keyboard\" or some other Input Application..." +
//					"Then, everything be ok!!!");
		}
		// />
	}
	
	public static void hideKeyboard(Context context, View v) {
		//Log.i(tag, "hideKeyboard()");
		InputMethodManager imm = (InputMethodManager) context
				.getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
	}

	/*
	 * Messages
	 */	
	public static void popupAlertMessage(Context context, int title, int message, int btnPositiveStringId) {
		new AlertDialog.Builder(context)
		.setTitle(title)
		.setMessage(message)
		.setPositiveButton(btnPositiveStringId, null)
		.create()
		.show();
	}

	public static void popupAlertMessage(Context context, int title,
			String message, int btnPositiveStringId) {
		new AlertDialog.Builder(context)
			.setTitle(title)
			.setMessage(message)
			.setPositiveButton(btnPositiveStringId, null)
			.create()
			.show();
	}

	public static void popupAlertMessage(Context context, String titleId, String message, int btnPositiveStringId) {
		new AlertDialog.Builder(context)
				.setTitle(titleId)
				.setMessage(message)
				.setPositiveButton(btnPositiveStringId, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {						
		
					}
				})
				.create()
				.show();
	}

	public static void makeShortToast(Context context, String content) {
		Toast.makeText(context, content, Toast.LENGTH_SHORT).show();
	}
	
	public static void makeShortToast(Context context, int content) {
		Toast.makeText(context, content, Toast.LENGTH_SHORT).show();
	}
	
	public static void makeToast(Context context, int contentId, int milisecond) {
		Toast.makeText(context, contentId, milisecond).show();
	}

	/**
	 * @author ttnlan
	 * This method make and show on the screen an alert. 
	 * @param context
	 * @param titleId: set -1 to show alert without title
	 * @param messageId
	 * @param btnPositiveNameId
	 * @param btnPositiveOnClickListener
	 * @param btnNegativeNameId
	 * @param btnNegativeOnClickListener
	 */
	public static void popAlert2Choose(Context context, int titleId, int messageId,
			int btnPositiveNameId, DialogInterface.OnClickListener btnPositiveOnClickListener,
			int btnNegativeNameId, DialogInterface.OnClickListener btnNegativeOnClickListener) {
		
		AlertDialog.Builder alert = new AlertDialog.Builder(context);
		if (titleId != -1) {
			alert.setTitle(titleId);
		}
		alert.setMessage(messageId)
			.setPositiveButton(btnPositiveNameId, btnPositiveOnClickListener)
			.setNegativeButton(btnNegativeNameId, btnNegativeOnClickListener)
			.create()
			.show();
	}
	
	public static void popAlert2Choose(Context context, int titleId, String[] messages, int index, 
			int btnPositiveNameId, DialogInterface.OnClickListener btnPositiveOnClickListener,
			int btnNegativeNameId, DialogInterface.OnClickListener btnNegativeOnClickListener) {
		
		AlertDialog.Builder alert = new AlertDialog.Builder(context);
		alert.setSingleChoiceItems(messages, index, null);
		if (titleId != -1) {
			alert.setTitle(titleId);
		}
		alert.setPositiveButton(btnPositiveNameId, btnPositiveOnClickListener)
			.setNegativeButton(btnNegativeNameId, btnNegativeOnClickListener)
			.create()
			.show();
	}
	
	public static void popAlert2Choose(Context context, 
			View layout, int titleId, int messageId,
			int btnPositiveNameId, DialogInterface.OnClickListener btnPositiveOnClickListener,
			int btnNegativeNameId, DialogInterface.OnClickListener btnNegativeOnClickListener) {
		
		AlertDialog.Builder alert = new AlertDialog.Builder(context);
		if (titleId != -1) {
			alert.setTitle(titleId);
		}
		if (messageId != -1) {
			alert.setMessage(messageId);
		}
		alert.setView(layout);
		alert.setPositiveButton(btnPositiveNameId, btnPositiveOnClickListener)
			.setNegativeButton(btnNegativeNameId, btnNegativeOnClickListener)
			.create()
			.show();
	}
	
	public static void popAlertToCallBack(
			Context context, final ICallBack callBack, final int callBackId, 
			int titleId, int messageId, int btnPositiveNameId, int btnNegativeNameId) {
		
		AlertDialog.Builder alert = new AlertDialog.Builder(context);
		if (titleId != -1) {
			alert.setTitle(titleId);
		}
		alert.setMessage(messageId)
			.setPositiveButton(btnPositiveNameId, new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					callBack.callBack(callBackId);
				}
			})
			.setNegativeButton(btnNegativeNameId, null)
			.create()
			.show();
	}
	
	public static void popAlertToCallBack(
			Context context, int titleId, int messageId, 
			int btnPositiveNameId, int btnNegativeNameId, 
			final Runnable runnable) {
		
		AlertDialog.Builder alert = new AlertDialog.Builder(context);
		if (titleId != -1) {
			alert.setTitle(titleId);
		}
		alert.setMessage(messageId)
			.setPositiveButton(btnPositiveNameId, new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					runnable.run();
				}
			})
			.setNegativeButton(btnNegativeNameId, null)
			.create()
			.show();
	}


	
	public static OnTouchListener createListenerForViewNotTransferTouchListenerForParent() {
		return new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				return true;
			}
		};
	}

	public static float getDeviceDimen(Context context, int dimenId) {
		Resources res = context.getResources();
		float dimen = res.getDimension(dimenId);
		float divider = res.getDisplayMetrics().density;
		if (divider != 0) {
			return dimen / divider;
		}
		return 0;
	}

//	UiUtilities.popAlert2Choose(this, "title", "messege", "ok", null, "1234568", null); // testing **
//	public static void popAlert2Choose(Context context, Object titleObject, String messageObject,
//			String btnPositiveNameObject, DialogInterface.OnClickListener btnPositiveOnClickListener,
//			String btnNegativeNameObject, DialogInterface.OnClickListener btnNegativeOnClickListener) {
//		
//		Object title;
//		Object message;
//		Object btnPositiveName;
//		Object btnNegativeName;
//		
//		try {
//			title = (Integer) Integer.parseInt(titleObject.toString());
//		} catch (NumberFormatException e) {
//			title = titleObject.toString();
//		}
//		
//		try {
//			message = Integer.parseInt(messageObject.toString());
//		} catch (NumberFormatException e) {
//			message = messageObject.toString();
//		}
//		
//		try {
//			btnPositiveName = Integer.parseInt(btnPositiveNameObject.toString());
//		} catch (NumberFormatException e) {
//			btnPositiveName = btnPositiveNameObject.toString();
//		}
//		
//		try {
//			btnNegativeName = Integer.parseInt(btnNegativeNameObject.toString());
//		} catch (NumberFormatException e) {
//			btnNegativeName = btnNegativeNameObject.toString();
//		}
//		
//		
//		new AlertDialog.Builder(context)
//			.setTitle(title.toString())
//			.setMessage(message.toString())
//			.setPositiveButton(btnPositiveName.toString(), btnPositiveOnClickListener)
//			.setNegativeButton(btnNegativeName.toString(), btnNegativeOnClickListener)
//			.create()
//			.show();
//	}
	
	/*
	 * Animations
	 */

	public static void setLayoutAnim_slideTopDown(ViewGroup panel) {

		AnimationSet set = new AnimationSet(true);

		Animation animation = new AlphaAnimation(0.0f, 1.0f);
		animation.setDuration(100);
		set.addAnimation(animation);

		animation = new TranslateAnimation(
				Animation.RELATIVE_TO_SELF, 0.0f,
				Animation.RELATIVE_TO_SELF, 0.0f, 
				Animation.RELATIVE_TO_SELF, -1.0f, 
				Animation.RELATIVE_TO_SELF, 0.0f);
		animation.setDuration(500);
		set.addAnimation(animation);

		LayoutAnimationController controller = 
				new LayoutAnimationController(set, 0.25f);

		panel.setLayoutAnimation(controller);
	}
	
	public static void setLayoutAnim_slideDownTop(ViewGroup panel) {

		AnimationSet set = new AnimationSet(true);

		Animation animation = new AlphaAnimation(0.0f, 1.0f);
		animation.setDuration(100);
		set.addAnimation(animation);

		animation = new TranslateAnimation(
				Animation.RELATIVE_TO_SELF, 0.0f,
				Animation.RELATIVE_TO_SELF, 0.0f, 
				Animation.RELATIVE_TO_SELF, 0.0f, 
				Animation.RELATIVE_TO_SELF, -1.0f);
		animation.setDuration(500);
		set.addAnimation(animation);

		LayoutAnimationController controller = 
				new LayoutAnimationController(set, 0.25f);

		panel.setLayoutAnimation(controller);
	}
	
	public static void setLayoutAnim_slideLeftRight(ViewGroup panel) {

		AnimationSet set = new AnimationSet(true);

		Animation animation = new AlphaAnimation(0.0f, 1.0f);
		animation.setDuration(100);
		set.addAnimation(animation);

		animation = new TranslateAnimation(
				Animation.RELATIVE_TO_SELF, 0.0f, // x start
				Animation.RELATIVE_TO_SELF, -1.0f, // x end
				Animation.RELATIVE_TO_SELF, 0.0f, // y start
				Animation.RELATIVE_TO_SELF, 0.0f); // y end
		animation.setDuration(500);
		set.addAnimation(animation);

		LayoutAnimationController controller = 
				new LayoutAnimationController(set, 0.25f);

		panel.setLayoutAnimation(controller);
	}

	public static void setLayoutAnimation2(Context ctx, ViewGroup panel, int animId) {

		LayoutAnimationController controller = AnimationUtils
				.loadLayoutAnimation(ctx, animId);

		panel.setLayoutAnimation(controller);

	}

	// ================================
	// Graphics Utilities
	// ================================
	/**
	 * This method return a bitmap from nine path image id with given width and height
	 * @param context
	 * @param drawableId
	 * @param w
	 * @param h
	 * @return
	 */
	public static Bitmap getBitmapFromNinepatch(Context context, int drawableId, int w, int h){
        // id is a resource id for a valid ninepatch

        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableId);

        byte[] chunk = bitmap.getNinePatchChunk();
        NinePatchDrawable np_drawable = new NinePatchDrawable(bitmap, chunk, new Rect(), null);
        np_drawable.setBounds(0, 0, w, h);

        Bitmap output_bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output_bitmap);
        np_drawable.draw(canvas);

        return output_bitmap;
    }

//	public static void popupCloseApp(final Activity context) {
//		popAlert2Choose(context, R.string.message, R.string.quit_app,  
//				R.string.yes, new OnClickListener() {
//					
//					@Override
//					public void onClick(DialogInterface dialog, int which) {
//						Intent intent = new Intent(context, UserMainModeActivity.class);
//						intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//						Utilities.savePreferences(context, "CloseApp", true);
//						context.finish();
//						context.startActivity(intent);
//						
//						Log.w(tag, "intent.putExtra(CloseApp, true);");
//					}
//				}, R.string.cancel, null);
//	}

	public static void startLauncherActivity(Activity act, String packageName, String appName) {
		final Intent intent = new Intent(Intent.ACTION_MAIN, null);
		intent.addCategory(Intent.CATEGORY_LAUNCHER);
		final ComponentName cn = new ComponentName(packageName, appName);
		intent.setComponent(cn);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		act.startActivity(intent);
	}

	public static void startACall(Context context, String number) {
	    try {
	        Intent callIntent = new Intent(Intent.ACTION_CALL);
	        callIntent.setData(Uri.parse("tel:" + number));
//	        Log.i(tag, "callIntent number="+number);
	        context.startActivity(callIntent);
	    } catch (ActivityNotFoundException e) {
	         Log.e("helloandroid dialing example", "Call failed", e);
	    }
	}

//	public static void showMessageRequestUserTurnOnNetwork(Context context) {
//		popupAlertMessage(context,
//				R.string.message_error_title,
//				R.string.message_turn_on_network);
//	}
}